﻿using System;
using System.Collections.Generic;
using System.IO;

namespace Pvf.Core.Converters
{
    internal sealed class PvfDictConverter<TKey, TValue> : PvfBinaryConverter<Dictionary<TKey, TValue>>
    {
        private IPvfConverter _keyConverter;
        private IPvfConverter _valueConverter;

        protected override void OnInit()
        {
            var keyType = Layout.ObjType.GetGenericArguments()[0];
            var valueType = Layout.ObjType.GetGenericArguments()[1];

            _keyConverter = PvfObjectBuilder.Build(keyType, Layout.Env);
            _valueConverter = PvfObjectBuilder.Build(valueType, Layout.Env);

            if (_keyConverter == null)
            {
                throw new NotSupportedException($"不支持的类型:{keyType.FullName}");
            }
            if (_valueConverter == null)
            {
                throw new NotSupportedException($"不支持的类型:{keyType.FullName}");
            }
        }

        private TKey ReadKey(BinaryReader reader, IPvfModule module)
        {
            return _keyConverter is IBinaryPvfConverter<TKey> binaryPvfConverter
                ? binaryPvfConverter.Deserialize(reader, module)
                : throw new NotSupportedException("不支持的转换器");
        }

        private TValue ReadValue(BinaryReader reader, IPvfModule module)
        {
            return _valueConverter is IBinaryPvfConverter<TValue> binaryPvfConverter
                ? binaryPvfConverter.Deserialize(reader, module)
                : throw new NotSupportedException("不支持的转换器");
        }

        public override Dictionary<TKey, TValue> Deserialize(BinaryReader reader, IPvfModule module = null)
        {
            var data = new Dictionary<TKey, TValue>();
            while (reader.PeekChar() != -1)
            {
                if (reader.IsEndOfStream())
                {
                    break;
                }

                if (_keyConverter is PvfConverterBase keyConverter)
                {
                    if (!keyConverter.CanRead(reader))
                    {
                        break;
                    }
                }

                var key = ReadKey(reader, module);

                if (_valueConverter is PvfConverterBase valueConverter)
                {
                    if (!valueConverter.CanRead(reader))
                    {
                        break;
                    }
                }

                var value = ReadValue(reader, module);

                data.Add(key, value);
            }
            return data;
        }
    }
}
